package alloy.transform.atomize;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import alloy.ast.LeafId;
import alloy.ast.Signature;
import alloy.type.SigType;

/**
 * Similar to the soon-to-be-deleted alloy.subscope.ScopedSigsInfo but provides
 * only the functionality I need for atomization
 */
class ScopeInfo {

	/**
	 * map from leaf ids of scoped sigs to names
	 */
	private final Map /* LeafId -> String */
	_id2SigName = new LinkedHashMap();

	/**
	 * leaf ids of scoped sigs
	 */
	private final Set /* of LeafId */
	_scopedSigIds = new LinkedHashSet();

	/**
	 * @param stringToType_
	 *            map from string signature names to their basic types
	 */
	ScopeInfo(Map stringToType_) {
		for (Iterator sigTypeIter = stringToType_.values().iterator(); sigTypeIter
				.hasNext();)
			// all signatures corresponding to basic types are scoped
			_handleScopedSig(((SigType) sigTypeIter.next()).getSignature());
	}

	/**
	 * @param sig_
	 *            a scoped signature. either a signature associated with a basic
	 *            type, or a disjoint signature extending exactly one scoped
	 *            signature.
	 */
	private void _handleScopedSig(Signature sig_) {
		String sigName = sig_.getTypedName();
		LeafId sigId = sig_.getLeafId();
		_scopedSigIds.add(sigId);
		_id2SigName.put(sigId, sigName);
	}

	/**
	 * @return the name of the scoped signature with leaf id id_, or
	 *         <code>null</code> if no scoped signature has leaf id id_
	 */
	public String getScopedSigName(LeafId id_) {
		return (String) _id2SigName.get(id_);
	}

	/**
	 * @return <code>true</code> if id_ corresponds to a scoped sig;
	 *         <code>false</code> otherwise
	 */
	public boolean isScopedSig(LeafId id_) {
		return _scopedSigIds.contains(id_);
	}
}
